# backend/utils/tokenizers.py
"""
多语言分词器模块
支持中文、泰语、越南语、印尼语的分词处理
"""
import re
import jieba
from pythainlp import word_tokenize as thai_word_tokenize
from typing import List, Dict

class MultiLanguageTokenizer:
    """多语言分词器"""

    def __init__(self):
        """初始化分词器"""
        # 设置jieba分词器
        jieba.setLogLevel(jieba.logging.INFO)  # 减少日志输出

        # 语言配置
        self.language_configs = {
            'zh': {
                'name': 'Chinese',
                # 定义中文字符的 Unicode 编码范围，\u4e00-\u9fff 是 CJK 统一汉字的基本区块
                # 汉字：一、二、三、我、你、他...，覆盖了绝大多数常用中文字符
                'unicode_ranges': [r'\u4e00-\u9fff'],
                'tokenizer_func': self._tokenize_chinese
            },
            'th': {
                'name': 'Thai',
                'unicode_ranges': [r'\u0e00-\u0e7f'],
                'tokenizer_func': self._tokenize_thai
            },
            'vi': {
                'name': 'Vietnamese',
                'unicode_ranges': [r'\u00c0-\u00ff', r'\u0100-\u01ef', r'\u1e00-\u1eff'],
                'tokenizer_func': self._tokenize_vietnamese
            },
            'id': {
                'name': 'Indonesian',
                'unicode_ranges': [r'\u0000-\u007f'],
                'tokenizer_func': self._tokenize_indonesian
            }
        }

    def _tokenize_chinese(self, text: str) -> List[str]:
        """中文分词"""
        # 使用jieba分词
        words = jieba.lcut(text)
        # 过滤掉空字符串和纯标点符号
        words = [word.strip() for word in words if word.strip() and not re.match(r'^[^\w\s]$', word)]
        return words

    def _tokenize_thai(self, text: str) -> List[str]:
        """泰语分词"""
        try:
            # 使用pythainlp分词
            words = thai_word_tokenize(text, engine='newmm')
            # 过滤掉空字符串和纯标点符号
            words = [word.strip() for word in words if word.strip() and not re.match(r'^[^\w\s\u0e00-\u0e7f]$', word)]
            return words
        except Exception as e:
            print(f"泰语分词错误: {e}")
            # 如果分词失败，使用字符级别分词
            return self._fallback_tokenize(text, 'th')

    def _tokenize_vietnamese(self, text: str) -> List[str]:
        """越南语分词 - 基于规则"""
        # 简单的基于空格和标点符号的分词
        # 越南语主要是以空格分隔的，但有一些特殊情况
        words = []
        # 先按空格分词
        tokens = text.split()
        for token in tokens:
            # 检查是否包含标点符号
            sub_tokens = re.findall(r'[\w\u00c0-\u00ff\u0100-\u01ef\u1e00-\u1eff]+|[^\s\w\u00c0-\u00ff\u0100-\u01ef\u1e00-\u1eff]', token)
            if sub_tokens:
                words.extend(sub_tokens)
            else:
                words.append(token)

        # 过滤和清理
        words = [word.strip() for word in words if word.strip() and len(word) > 1]
        return words

    def _tokenize_indonesian(self, text: str) -> List[str]:
        """印尼语分词 - 基于规则"""
        # 印尼语主要使用空格分词
        words = []
        tokens = text.split()
        for token in tokens:
            # 简单的标点符号处理
            sub_tokens = re.findall(r'\w+|[^\w\s]', token)
            if sub_tokens:
                words.extend(sub_tokens)

        # 过滤和清理
        words = [word.strip() for word in words if word.strip() and len(word) > 1]
        return words

    def _fallback_tokenize(self, text: str, lang: str) -> List[str]:
        """回退分词器 - 基于字符和规则"""
        if lang == 'th':
            # 泰语字符级分词，保留有意义的字符组合
            tokens = re.findall(r'[\u0e00-\u0e7f]+|[a-zA-Z0-9]+|[^\u0e00-\u0e7fa-zA-Z0-9\s]', text)
        else:
            # 其他语言的通用分词
            tokens = re.findall(r'\w+|[^\w\s]', text)

        return [token.strip() for token in tokens if token.strip()]

    def tokenize(self, text: str, lang: str) -> List[str]:
        """
        根据语言对文本进行分词

        Args:
            text: 要分词的文本
            lang: 语言代码 ('zh', 'th', 'vi', 'id')

        Returns:
            分词结果列表
        """
        if not text or not isinstance(text, str):
            return []

        text = text.strip()
        if not text:
            return []

        # 获取语言配置
        lang_config = self.language_configs.get(lang)
        if not lang_config:
            raise ValueError(f"不支持的语言: {lang}")

        # 使用对应的分词器
        try:
            tokens = lang_config['tokenizer_func'](text)
            return tokens
        except Exception as e:
            print(f"分词失败 ({lang}): {e}")
            # 使用回退分词器
            return self._fallback_tokenize(text, lang)

    def get_supported_languages(self) -> Dict[str, str]:
        """获取支持的语言列表"""
        return {code: config['name'] for code, config in self.language_configs.items()}

    def detect_language_features(self, text: str) -> Dict[str, float]:
        """
        检测文本中各语言字符的比例

        Args:
            text: 要检测的文本

        Returns:
            各语言字符比例的字典
        """
        if not text:
            return {}

        total_chars = len(text)
        language_scores = {}

        for lang_code, config in self.language_configs.items():
            pattern = '[' + ''.join(config['unicode_ranges']) + ']'
            matches = re.findall(pattern, text)
            lang_chars = len(''.join(matches))
            language_scores[lang_code] = lang_chars / total_chars if total_chars > 0 else 0

        return language_scores